package com.manager.container.service.impl;

import com.manager.common.customer.utils.RemoteApi;
import com.manager.common.dao.SuperDao;
import com.manager.common.utils.DataTools;
import com.manager.common.utils.ObjectUtils;
import com.manager.common.vo.PageVO;
import com.manager.common.vo.ResultVO;
import com.manager.container.service.DockerDeployService;
import com.manager.model.*;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@Transactional
public class DockerDeployServiceImpl extends SuperDao<Object> implements DockerDeployService {

    @Override
    public PageVO getRealContainerInfo(DockerDeploy model) throws Exception {
        List<Object> params = new ArrayList<>();
        String sql = " from tb_docker_deploy t LEFT JOIN tb_docker_images ti on t.docker_images_table_id = ti.table_id " +
                " LEFT JOIN tb_docker_deploy_network dn on dn.deploy_table_id = t.table_id where 1=1 ";
        if(StringUtils.isNotEmpty(model.getContainerName())){
            sql += " and t.container_name like # ";
            params.add("%"+model.getContainerName()+"%");
        }
        if(model.getDeployState() != null){
            sql += " and t.deploy_state = # ";
            params.add(model.getDeployState());
        }
        if(StringUtils.isNotEmpty(model.getContainerID())){
            sql += " and t.containerid like # ";
            params.add("%"+model.getContainerID()+"%");
        }
        sql += "  GROUP BY t.table_id ";
        sql = ObjectUtils.replaceIndexByList(sql,params);
        List<DockerDeploy> list = this.getListByColumSQL(" SELECT t.*,ti.`name` as imageName,ti.tag as imageTag," +
                " ti.image_id as imageID ,GROUP_CONCAT(dn.host_port) as ports "
                        + sql,params,model.getStart(),model.getLimit(),DockerDeploy.class);
        int sum = this.getListCountSql("select count(*) " + sql,params.toArray(),"");
        int count = (int)Math.ceil(Double.valueOf(sum)/Double.valueOf(model.getLimit()));
        String url = DataTools.getSystemSettingStringValByKey("get_container_real_time_info_url");

        try {
            ResultVO<JSONArray> resultVO = RemoteApi.executeHttp(url);
            if(resultVO.getCode() == 1){
                JSONArray array = resultVO.getData();
                for(DockerDeploy dockerDeploy:list){
                    for(int i = 0; i < array.size() ; i++){
                        JSONObject object = array.getJSONObject(i);
                        DockerContainerStats dockerContainerStats = (DockerContainerStats) JSONObject.toBean(object,DockerContainerStats.class);
                        if(dockerDeploy.getContainerID().equals(dockerContainerStats.getContainerId())){
                            dockerDeploy.setRealTimeCpu(dockerContainerStats.getUseCpuPercent());
                            dockerDeploy.setRealTimeMemory(dockerContainerStats.getUseMemoryPercent());
                            dockerDeploy.setRealTimeNetwork(dockerContainerStats.getUseNetworkIn());
                            break;
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return PageVO.create(model.getStart(),count,ObjectUtils.getJSONArray(DockerDeploy.config,list));
    }

    @Override
    public PageVO getDeployPage(DockerDeploy model) throws Exception{
        List<Object> params = new ArrayList<>();
        String sql = " from tb_docker_deploy t LEFT JOIN tb_docker_images ti on t.docker_images_table_id = ti.table_id where 1=1 ";
        if(StringUtils.isNotEmpty(model.getContainerName())){
            sql += " and t.container_name like # ";
            params.add("%"+model.getContainerName()+"%");
        }
        if(model.getDeployState() != null){
            sql += " and t.deploy_state = # ";
            params.add(model.getDeployState());
        }
        sql = ObjectUtils.replaceIndexByList(sql,params);
        List<DockerDeploy> list = this.getListByColumSQL(" SELECT t.*,ti.`name` as imageName,ti.image_id as imageID " + sql,
                params,model.getStart(),model.getLimit(),DockerDeploy.class);
        int sum = this.getListCountSql("select count(*) " + sql,params.toArray(),"");
        int count = (int)Math.ceil(Double.valueOf(sum)/Double.valueOf(model.getLimit()));
        return PageVO.create(model.getStart(),count,ObjectUtils.getJSONArray(DockerDeploy.config,list));
    }

    @Override
    public void addDeploy(DockerDeploy model) {
        this.addT(model);
    }

    @Override
    public void updateDeploy(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setContainerName(model.getContainerName());
        dockerDeploy.setContainerType(model.getContainerType());
        this.updateT(dockerDeploy);
    }

    @Override
    public void deleteDeploy(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        this.delete(dockerDeploy);
    }

    @Override
    public List<DockerDeploy> getNoDeployedContainerList() {
        String sql = " from DockerDeploy t where t.deployState in (0,-1) ";
        List<DockerDeploy> list  = this.getList(sql,0,0,"");
        return list;
    }

    @Override
    public List<DockerDeploy> getDeployedContainerList() {
        String sql = " from DockerDeploy t where t.deployState not in (0,-1) ";
        List<DockerDeploy> list  = this.getList(sql,0,0,"");
        return list;
    }

    @Override
    public void updateBaseInfo(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        DockerImages dockerImages = this.getT(model.getDockerImages().getId(),DockerImages.class);

        dockerDeploy.setDockerImages(dockerImages);
        dockerDeploy.setContainerType(model.getContainerType());
        dockerDeploy.setHasEnter(model.getHasEnter());
        dockerDeploy.setProcessName(model.getProcessName());
        dockerDeploy.setRunModel(model.getRunModel());

        this.updateT(dockerDeploy);
    }

    @Override
    public void updateResourceInfo(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setCpu(model.getCpu());
        dockerDeploy.setMemory(model.getMemory());
        dockerDeploy.setDisk(model.getDisk());
        this.updateT(dockerDeploy);
    }

    @Override
    public void updateDockerEnvFilePath(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setDockerEnvFilePath(model.getDockerEnvFilePath());
        this.updateT(dockerDeploy);
    }

    @Override
    public void updateParamsFilePath(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setParamsFilePath(model.getParamsFilePath());
        dockerDeploy.setParamsFileType(model.getParamsFileType());
        this.updateT(dockerDeploy);
    }

    @Override
    public void updateCustomParams(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setInterfaceAddress(model.getInterfaceAddress());
        dockerDeploy.setRequestType(model.getRequestType());
        dockerDeploy.setInterfaceDesc(model.getInterfaceDesc());
        dockerDeploy.setSettingFilePath(model.getSettingFilePath());
        dockerDeploy.setDbName(model.getDbName());
        dockerDeploy.setDbIp(model.getDbIp());
        dockerDeploy.setDbUserName(model.getDbUserName());
        dockerDeploy.setDbPassword(model.getDbPassword());
        this.updateT(dockerDeploy);
    }

    @Override
    public void updateVolumes(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setVolumeType(model.getVolumeType());
        this.batchDelete(dockerDeploy.getDockerDeployVolumeList());
        List<DockerDeployVolume> dockerDeployVolumeList = model.getDockerDeployVolumeList();
        if(dockerDeployVolumeList != null && dockerDeployVolumeList.size() > 0){
            for(DockerDeployVolume dockerDeployVolume:dockerDeployVolumeList){
                dockerDeployVolume.setVolumeType(model.getVolumeType());
                dockerDeployVolume.setDeploy(dockerDeploy);
                this.addT(dockerDeployVolume);
            }
        }
    }

    @Override
    public void updateNetwork(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setNetworkIp(model.getNetworkIp());
        dockerDeploy.setNetworkName(model.getNetworkName());
        this.batchDelete(dockerDeploy.getDockerDeployNetworkList());
        List<DockerDeployNetwork> dockerDeployNetworkList = model.getDockerDeployNetworkList();
        if(dockerDeployNetworkList != null && dockerDeployNetworkList.size() > 0){
            for(DockerDeployNetwork dockerDeployNetwork:dockerDeployNetworkList){
                dockerDeployNetwork.setDeploy(dockerDeploy);
                this.addT(dockerDeployNetwork);
            }
        }
    }

    @Override
    public DockerDeploy getDockerDeployById(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        return dockerDeploy;
    }

    @Override
    public void updateContainerDeployInfo(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(model.getId(),DockerDeploy.class);
        dockerDeploy.setContainerID(model.getContainerID());
        dockerDeploy.setDeployState(model.getDeployState());
        dockerDeploy.setRunState(model.getRunState());
        this.updateT(dockerDeploy);
    }

    @Override
    public void updateContainerBackupCorn(DockerDeploy model) {
        DockerDeploy dockerDeploy = this.getT(DockerDeploy.class,model.getId());
        dockerDeploy.setHasEnableBackup(model.getHasEnableBackup());
        dockerDeploy.setScheduledCorn(model.getScheduledCorn());
        this.updateT(dockerDeploy);
    }

    @Override
    public List<DockerDeployVolume> getDockerDeployVolumeList(DockerDeploy model) {
        String sql = "from DockerDeployVolume t where t.deploy.id = ?1";
        List<DockerDeployVolume> list = this.getList(sql,new Object[]{model.getId()},0,0,"");
        return list;
    }

    @Override
    public List<DockerDeployVolume> getDockerDeployVolumeList(String id) {
        String sql = "from DockerDeployVolume t where t.deploy.id = ?1";
        List<DockerDeployVolume> list = this.getList(sql,new Object[]{id},0,0,"");
        return list;
    }

    @Override
    public List<DockerDeploy> getDockerDeployBackupList() {
        String sql = " from DockerDeploy t where t.hasEnableBackup = ?1 ";
        List<DockerDeploy> list = this.getList(sql,new Object[]{1},0,0,"");
        return list;
    }

    @Override
    public DockerDeploy getDockerDeployById(String id) {
        return this.getT(DockerDeploy.class,id);
    }

    @Override
    public List<DockerDeploy> getDockerDeployByIds(String ids) {
        List<String> list = ObjectUtils.jsonArray2Bean(ids,String.class);
        String whereIds = "'" +  StringUtils.join(list,"','") + "'";
        String sql = " from DockerDeploy t where  t.id in  (" + whereIds +")";
        List<DockerDeploy> result = this.getList(sql,new Object[]{},0,0,"");
        return result;
    }
}
